//
//  CompressVideoManager.swift
//  TestDemo
//
//  Created by ayin on 2019/2/17.
//  Copyright © 2019 aYin. All rights reserved.
//  视频压缩

import Foundation
import PLPlayerKit
import PLShortVideoKit

enum CompressVideoState {
    case success
    case error
    case cancel
}

class CompressVideoManager: NSObject {
    static let shared = CompressVideoManager()
    
    //MARK: - 压缩方法
    //系统压缩
    func systemCompressVideo(_ videoUrl: URL,outputVideoUrl: URL,_ progress: @escaping ((_ progress: CGFloat) -> Void),_ completion: @escaping ((_ compressResult: CompressVideoState, _ url: URL?) -> Void)) {
        let avURLAsset = AVURLAsset.init(url: videoUrl)
        guard let assetExport = AVAssetExportSession(asset: avURLAsset, presetName: AVAssetExportPresetMediumQuality) else {
            return
        }
        assetExport.outputFileType = .mp4// 输出类型
        assetExport.outputURL = outputVideoUrl// 输出地址
        assetExport.shouldOptimizeForNetworkUse = true// 优化
        
        let outputFilePath = outputVideoUrl.relativePath
        if FileManager.default.fileExists(atPath: outputFilePath) {
            completion(.success ,outputVideoUrl)
            return
        }
        
        assetExport.exportAsynchronously(completionHandler: {
            switch assetExport.status {
            case .unknown:
                print("----------------unknown")
            case .waiting:
                print("----------------waiting")
            case .exporting:
                print("----------------exporting")
            case .completed:
                //转码压缩成功
                completion(.success ,outputVideoUrl)
                self.printVideoInfo(outputFilePath)
            case .failed:
                completion(.error ,nil)
            case .cancelled:
                completion(.cancel ,nil)
            }
        })
    }
    
    //七牛压缩
    func qiniuCompressVideo(_ videoUrl: URL,outputVideoUrl: URL,_ progress: @escaping ((_ progress: Float) -> Void),_ completion: @escaping ((_ compressResult: CompressVideoState, _ url: URL?) -> Void)) {
        let transcoder:PLShortVideoTranscoder = PLShortVideoTranscoder(url: videoUrl)
        transcoder.outputURL = outputVideoUrl
//        transcoder.outputFileType = .MPEG4
//        transcoder.outputFilePreset = .preset960x540
        transcoder.bitrate = 1000 * 1000// 设置码率
        transcoder.completionBlock = { url in
            completion(.success ,url)
            self.printVideoInfo((url?.relativePath)!)
        }
        transcoder.failureBlock = { error in
            completion(.error ,nil)
        }
        transcoder.processingBlock = { process in
            progress(process)
        }
        transcoder.startTranscoding()
    }
    
    //自定义压缩
    func customCompressVideo(_ videoUrl: URL,outputVideoUrl: URL,_ progress: @escaping ((_ value: Float) -> Void),_ completion: @escaping ((_ compressResult: CompressVideoState, _ url: URL?) -> Void)) {
        let avAsset = AVAsset(url: videoUrl)
        let encoder = SDAVAssetExportSession(asset: avAsset)
        encoder?.outputFileType = AVFileType.mp4.rawValue
        encoder?.outputURL = outputVideoUrl
        encoder?.videoSettings = self.videoCompressSettings()
        encoder?.audioSettings = self.audioCompressSettings()
        
        encoder?.exportAsynchronously(progress: { (value) in
            progress(value)
        }, completionHandler: {
            if encoder?.status == .completed {
                //转码成功
                completion(.success ,outputVideoUrl)
                self.printVideoInfo(outputVideoUrl.relativePath)
            }else if encoder?.status == .cancelled {
                completion(.cancel ,nil)
            }else {
                completion(.error ,nil)
                print("error:----------\(encoder?.error.localizedDescription ?? "")")
            }
        })
    }
    
    //指定音视频的压缩码率，profile，帧率等关键参数信息
    func videoCompressSettings() -> [String : Any] {
        let compressionProperties: [String : Any] = [AVVideoAverageBitRateKey : 1000 * 1000,
                                                     AVVideoExpectedSourceFrameRateKey : 25,
                                                     AVVideoProfileLevelKey : AVVideoProfileLevelH264HighAutoLevel]
        let videoCompreesSetings: [String : Any] = [AVVideoCodecKey : AVVideoCodecH264,
                                                    AVVideoWidthKey : 540,
                                                    AVVideoHeightKey : 960,
                                                    AVVideoCompressionPropertiesKey :compressionProperties]
        return videoCompreesSetings
    }
    
    func audioCompressSettings() -> [String: Any] {
        var stereoChannelLayout = AudioChannelLayout()
        stereoChannelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo
        stereoChannelLayout.mChannelBitmap = .bit_Left
        stereoChannelLayout.mNumberChannelDescriptions = 0
        let channelLayoutAsData = Data.init(bytes: &stereoChannelLayout, count: 100)
        let audioCompressSettings: [String : Any] = [AVFormatIDKey : kAudioFormatMPEG4AAC,
                                                     AVEncoderBitRateKey : 96000,
                                                     AVSampleRateKey : 44100,
                                                     AVNumberOfChannelsKey : 2,
                                                     AVChannelLayoutKey : channelLayoutAsData]
        return audioCompressSettings
    }
    
    //MARK: - 其他
    //打印
    func printVideoInfo(_ filePath:String) {
        let now = Date()
        let dformatter = DateFormatter()
        dformatter.dateFormat = "yyyy年MM月dd日 HH:mm:ss"
        
        filePath.getFileSize { (size,error) in
            let recordSize = size!/1024/1024
            print("当前时间：\(dformatter.string(from: now as Date))，视频大小：\(recordSize)")
        }
    }
}
